package com.w.picture.controller;

import com.w.picture.annotation.RoleCheck;
import com.w.picture.common.BaseResponse;
import com.w.picture.common.ResultUtils;
import com.w.picture.constans.UserConstant;
import com.w.picture.exception.BusinessException;
import com.w.picture.exception.ErrorCode;
import com.w.picture.manager.CosManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;

/**
 * @Title: FileController
 * @Author wzp
 * @Date 2024/12/30 18:29
 * @description: 文件上传
 */
@Slf4j
@RestController
@RequestMapping("/file")
public class FileController {
    @Resource
    private CosManager cosManager;

    /**
     * @param multipartFile
     * @return
     * @RequestPart 注解介绍
     * 1. 用途
     * 处理 multipart 表单数据：主要用于接收和解析 multipart/form-data 类型的 HTTP 请求中的部分数据。这类请求通常用于文件上传以及同时提交其他表单字段。
     * 支持复杂的数据结构：不仅可以接收文件（如 MultipartFile），还可以接收其他类型的数据（如 JSON、XML 等），作为 multipart 请求的一部分。
     * 2. 适用场景
     * 文件上传：当需要上传文件时，@RequestPart 可以用来接收 MultipartFile 对象。
     * 多部分表单数据：当需要同时上传文件和其他表单字段时，使用 @RequestPart 来分别接收不同的部分。
     * 3. 参数说明
     * name：指定 multipart 请求中部分的名称，默认是从方法参数名推断。例如 @RequestPart("file") 指定了该部分的名称为 "file"。
     * required：布尔值，表示该部分是否必须存在，默认为 true。如果设置为 false，则即使请求中缺少该部分，也不会抛出异常。
     * defaultValue：提供默认值，仅当 required=false 且实际请求中没有提供相应部分时生效。
     * consumes：指定该部分可以接受的内容类型（媒体类型），例如 MediaType.APPLICATION_JSON_VALUE 或 MediaType.MULTIPART_FORM_DATA_VALUE。
     * 4.与 @RequestParam 的区别
     * 虽然 @RequestParam 也可以接收 MultipartFile，但 @RequestPart 更加语义化，明确地表达了对 multipart 请求部分的处理意图，特别是在复杂的 multipart 请求场景下更为推荐。
     */
    @RoleCheck(UserConstant.ADMIN_ROLE)
    @PostMapping("/upload")
    public BaseResponse<String> uploadFile(@RequestPart("file") MultipartFile multipartFile) {
        // 文件目录
        String filename = multipartFile.getOriginalFilename();
        String filepath = String.format("/test/%s", filename);
        File file = null;
        try {
            // 上传文件
            file = File.createTempFile(filepath, null);
            multipartFile.transferTo(file);
            cosManager.putObject(filepath, file,null);
            // 返回可访问地址
            return ResultUtils.success(filepath);
        } catch (Exception e) {
            log.error("file upload error, filepath = " + filepath, e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR.getCode(), "上传失败");
        } finally {
            if (file != null) {
                // 删除临时文件
                boolean delete = file.delete();
                if (!delete) {
                    log.error("file delete error, filepath = {}", filepath);
                }
            }
        }
    }
}
